package com.naza.rpc.serialize.protostuff;

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import static com.naza.rpc.core.RpcSystemConfig.SERIALIZE_POOL_MAX_TOTAL;
import static com.naza.rpc.core.RpcSystemConfig.SERIALIZE_POOL_MIN_IDLE;
import static com.naza.rpc.core.RpcSystemConfig.SERIALIZE_POOL_MAX_WAIT_MILLIS;
import static com.naza.rpc.core.RpcSystemConfig.SERIALIZE_POOL_MIN_EVICTABLE_IDLE_TIME_MILLIS;

/**
 * @author yl
 */
public class ProtostuffSerializePool
{
    private GenericObjectPool<ProtostuffSerialize> protostuffPool;

    private static volatile ProtostuffSerializePool poolFactory = null;

    @SuppressWarnings("unused")
    private ProtostuffSerializePool()
    {
        protostuffPool = new GenericObjectPool<ProtostuffSerialize>(
                new ProtostuffSerializeFactory());
    }

    public static ProtostuffSerializePool getProtostuffPoolInstance()
    {
        if (poolFactory == null)
        {
            synchronized (ProtostuffSerializePool.class)
            {
                if (poolFactory == null)
                {
                    poolFactory = new ProtostuffSerializePool(
                            SERIALIZE_POOL_MAX_TOTAL, SERIALIZE_POOL_MIN_IDLE,
                            SERIALIZE_POOL_MAX_WAIT_MILLIS,
                            SERIALIZE_POOL_MIN_EVICTABLE_IDLE_TIME_MILLIS);
                }
            }
        }
        return poolFactory;
    }

    public ProtostuffSerializePool(final int maxTotal, final int minIdle,
            final long maxWaitMillis, final long minEvictableIdleTimeMillis)
    {
        protostuffPool = new GenericObjectPool<ProtostuffSerialize>(
                new ProtostuffSerializeFactory());

        GenericObjectPoolConfig config = new GenericObjectPoolConfig();

        config.setMaxTotal(maxTotal);
        config.setMinIdle(minIdle);
        config.setMaxWaitMillis(maxWaitMillis);
        config.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);

        protostuffPool.setConfig(config);
    }

    public ProtostuffSerialize borrow()
    {
        try
        {
            return getProtostuffPool().borrowObject();
        }
        catch (final Exception ex)
        {
            ex.printStackTrace();
            return null;
        }
    }

    public void restore(final ProtostuffSerialize object)
    {
        getProtostuffPool().returnObject(object);
    }

    public GenericObjectPool<ProtostuffSerialize> getProtostuffPool()
    {
        return protostuffPool;
    }
}
